import Vue from 'vue'
import Router from 'vue-router'
import Api from '@/http/api'
import Store from '@/store'
import Cookies from "js-cookie"
import {clearLoginInfo} from "@/utils"

Vue.use(Router);

/*引入组件*/
import ShowMain from '@/views/common/show/showMain'
import MainSider from '@/views/common/show/mainSider'
import ShowHome from '@/views/modules/show/home'
import Search from '@/views/modules/show/article/search'
import Label from '@/views/modules/show/article/label'

import Login from '@/views/common/sys/login'
import LoginEmail from '@/views/common/sys/loginEmail'
import Register from '@/views/common/sys/register'
import Main from '@/views/common/sys/main'
import Home from '@/views/modules/sys/home'

import Error from '@/views/common/error/error'
import ErrorXXX from '@/views/common/error/errorXXX'
import ErrorNet from '@/views/common/error/errorNetFail'
import Timeout from '@/views/common/error/timeout'


/*相同路由点击报错问题*/
//获取原型对象上的push函数
const originalPush = Router.prototype.push
//修改原型对象中的push方法
Router.prototype.push = function push(location) {
    return originalPush.call(this, location).catch(err => err)
}


const router = new Router({
    routes: [
        {
            path: '/',
            name: 'showMain',
            component: ShowMain,
            meta: {
                type: 'route',
                icon: '',
            },
            // 子路由
            children: [
                {
                    path: '',
                    name: 'mainSider',
                    component: MainSider,
                    meta: {
                        type: 'route',
                        icon: '',
                        title: '首页'
                    },
                    children: [
                        {
                            path: '',
                            name: 'showHome',
                            component: ShowHome,
                            meta: {
                                type: 'route',
                                icon: '',
                                title: '首页'
                            },
                        }
                    ],

                },
                {
                    path: '/login',
                    name: 'login',
                    component: Login,
                    meta: {
                        type: 'route',
                        icon: '',
                    },
                },
                {
                    path: '/login/email',
                    name: 'loginEmail',
                    component: LoginEmail,
                    meta: {
                        type: 'route',
                        icon: '',
                    },
                },
                {
                    path: '/register',
                    name: 'register',
                    component: Register,
                    meta: {
                        type: 'route',
                        icon: '',
                    },
                },
                {
                    path: '/search',
                    name: 'search',
                    component: Search,
                    meta: {
                        type: 'route',
                        icon: '',
                    },
                },
                {
                    path: '/label',
                    name: 'label',
                    component: Label,
                    meta: {
                        type: 'route',
                        icon: '',
                    },
                },

            ]
        },
        {
            path: '/sys',
            name: 'sysMain',
            component: Main,
            meta: {
                type: 'route',
                icon: '',
            },
            // 子路由
            children: [
                {
                    path: '',
                    name: 'home',
                    component: Home,
                    meta: {
                        type: 'route',
                        icon: '',
                        title: '首页'
                    },
                },
            ]
        },
        {
            path: '/error',
            name: 'error',
            component: Error,
            meta: {
                type: 'route',
                icon: '',
            },
        },
        {
            path: '/error/xxx',
            name: 'xxx',
            component: ErrorXXX,
            meta: {
                type: 'route',
                icon: '',
            },
        },
        {
            path: '/error/errorNet',
            name: 'errorNet',
            component: ErrorNet,
            meta: {
                type: 'route',
                icon: '',
            },
        },
        {
            path: '/error/timeout',
            name: 'timeout',
            component: Timeout,
            meta: {
                type: 'route',
                icon: '',
            },
        },
    ]
});


//router路由限制
router.beforeEach((to, from, next) => {

    //初始化前端路由
    initSysShowMenuRoute();

    //检测cookie有效时间，无效直接开始清除原来的时间，有效迭代时间。
    let result = checkCookieAndRefresh();
    if(!result){
        //清除 浏览器信息
        next();
        return;
    }


    //登录后处理 --
    if ('/sys' == to.path || '/sys/' == to.path) {

        // 初始化后端路由
        initSysMenuRoute();

        // 初始化用户信息和权限信息
        initUserInfoAndPermissions();

    } else { //放置重复添加路由
        //从sessionStorage重置vuex的路由，用户信息、
        resetVuexRouteUserInitRouteInfo();
    }

    next();

});

let checkCookieAndRefresh =()=>{

    let token = Cookies.get('token');
    if(!token){
        clearLoginInfo();
        return false;
    }

    //设置cookie 两小时后过期
    var millisecond = new Date().getTime();
    var expiresTime = new Date(millisecond + 2 * 60 * 60 * 1000);
    Cookies.set('token', token, {
        expires: expiresTime,
    });
    return true;

}

/* 每次跳转 重置用户信息、权限信息、菜单信息    */
let resetVuexRouteUserInitRouteInfo = () => {

    if (Store.state.common.menuList.length > 0) {
        return;
    }

    let menuList = JSON.parse(sessionStorage.getItem('menuList') || '[]')
    Store.commit('updateMenuList', menuList);
    console.log("【后端菜单配置 - 再次加载】-- 获取本地存储的动态菜单 - 未配置路由 - 成功");
    console.log(menuList);

    let userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}')
    Store.commit('updateUserInfo', userInfo);

    let permissions = JSON.parse(sessionStorage.getItem('permissions') || '[]')
    Store.commit('updatePermissions', permissions);

    // 添加定时，做延迟，不延迟出现刷新无法跳转问题
    setTimeout(() => {
        //配置路由
        let dynamicRoutes = addDynamicRoutes(menuList)
        router.options.routes[1].children = router.options.routes[1].children.concat(dynamicRoutes)
        router.addRoutes(router.options.routes);

        console.log('【后端重置-再次加载用户信息-vuex-sessionStorage】 后端动态路由成功----------.');
        console.log(router);
    }, 100);


};

let initUserInfoAndPermissions = () => {

    //若存在不执行获取
    let storeMenuList = Store.state.common.userInfo;
    if (storeMenuList.length > 0) {
        console.log('【初始化用户信息】 -- 用户信息已存在，不需要重新获取');
        return;
    }

    Api.User.info()
            .then(res => {
                if (res.code == 0 && res.user) {
                    //设置 sessionStorage 获取
                    sessionStorage.setItem('userInfo', JSON.stringify(res.user || '{}'));
                    Store.commit('updateUserInfo', res.user);
                    console.log("【初始化用户信息】 -- OK" );
                    console.log(res.user);
                }
            }).catch(res => {

    });

    Api.User.permissions()
            .then(res => {
                if (res.code == 0 && res.permissions) {

                    //设置 sessionStorage 获取
                    sessionStorage.setItem('permissions', JSON.stringify(res.permissions || '[]'));
                    Store.commit('updatePermissions', res.permissions);
                    console.log("【初始化权限信息】 -- OK" );
                    console.log(res.permissions);
                }
            }).catch(res => {

    });


}

/* 初始化前端菜单列表 */
let initSysShowMenuRoute = () =>{

    //若存在不执行获取
    let storeShowMenuList = Store.state.common.showMenuList;
    if (storeShowMenuList.length > 0) {
        console.log('【初始化前端菜单列表】 -- 前端系统菜单已存在，不需要重新获取');
        return;
    }

    //获取菜单信息
    Api.Menu.showNav()
            .then(res => {
                let menuList = new Array(); //切换成单点形式 - 取消树状
                res.menuList.map(menu => {

                    if (menu.url) {
                        let tempArray = menu.url.split('/');
                        menu['index'] = tempArray[tempArray.length - 1];
                    }
                    let list = menu.list;
                    if (list) { //最多二级 url初始化index，作为菜单的唯一标识
                        menu.list = list.map(m => {
                            if (m.url) {
                                let tempArray = m.url.split('/');
                                m['index'] = tempArray[tempArray.length - 1];
                                return m;
                            }
                        })
                        menuList = menuList.concat(menu.list);
                    }
                    return menu;
                });

                //设置 sessionStorage 获取
                sessionStorage.setItem('showMenuList', JSON.stringify(menuList || '[]'));

                Store.commit('updateShowMenuList', menuList);
                console.log('【初始化前端菜单列表】 -- 获取数据成功 - 数据为');
                console.log(menuList);

                //配置路由
                let dynamicRoutes = addDynamicRoutes(menuList)
                router.options.routes[0].children[0].children = router.options.routes[0].children[0].children.concat(dynamicRoutes)
                router.addRoutes(router.options.routes);

                console.log('【初始化前端菜单列表】 -- 路由整理情况 - 数据为');
                console.log(router);

            })
            .catch(res => {
                console.log('【初始化前端菜单列表】 -- 动态菜单和路由失败 - 错误信息：')
                console.log(res);
            });
}


/* 初始化后端菜单列表 */
let initSysMenuRoute = () => {

    //若存在不执行获取
    let storeMenuList = Store.state.common.menuList;
    if (storeMenuList.length > 0) {
        console.log('【初始化后端菜单列表】 -- 系统菜单已存在，不需要重新获取');
        return;
    }

    //获取菜单信息
    Api.Menu.nav()
            .then(res => {
                let menuList = res.menuList.map(menu => {
                    if (menu.url) {
                        let tempArray = menu.url.split('/');
                        menu['index'] = tempArray[tempArray.length - 1];
                    }
                    let list = menu.list;
                    if (list) { //最多二级 url初始化index，作为菜单的唯一标识
                        menu.list = list.map(m => {
                            if (m.url) {
                                let tempArray = m.url.split('/');
                                m['index'] = tempArray[tempArray.length - 1]; //获取当前路径的最后一个单词，用作名称
                                return m;
                            }
                        })
                    }
                    return menu;
                });


                //设置 sessionStorage 获取
                sessionStorage.setItem('menuList', JSON.stringify(menuList || '[]'));

                Store.commit('updateMenuList', menuList);
                console.log('【初始化后端菜单列表】 -- 初始化后端动态菜单成功 - 数据为');
                console.log(menuList);

                //配置路由
                let dynamicRoutes = addDynamicRoutes(menuList)
                router.options.routes[1].children = router.options.routes[1].children.concat(dynamicRoutes)
                router.addRoutes(router.options.routes);

                console.log('【初始化后端菜单列表】 -- 初始化后端动态路由成功 - 数据为');
                console.log(router);

            })
            .catch(res => {
                console.log('【初始化后端菜单列表】 -- 初始化后端动态菜单和路由失败 - 错误信息');
                console.log(res);
            });
};

/* 解析菜单配置路由
 *  菜单 =》 路由对应关系：
 *      index   -》  name
 *      url     -》  path
 *      name    -》  title
 * */
let addDynamicRoutes = (menuList = [], routes = []) => {

    let temp = [];
    for (let i = 0; i < menuList.length; i++) {
        let menu = menuList[i];
        let url = menu.url;
        if (menu.list && menu.list.length >= 1) {
            temp = temp.concat(menu.list)

            //菜单路由包含子菜单按钮 - 增加路由映射
            if(menu.url && /\S/.test(menu.url)){
                routes = menuUrl2Route(url,menu,routes);
            }

        } else if (/^http[s]?:\/\/.*/.test(menu.url)) { //处理jframe
            let route = {
                path: null,
                component: null,
                name: menu.index,
                meta: {
                    type: 'iframe',
                    icon: menu.icon,
                    title: menu.name,
                    url: url
                }
            };

            // 如果是嵌套页面, 通过iframe展示
            let iframePath = url.replace(/^http[s]?:\/\//, '');
            route['path'] = '/'+iframePath.substring(iframePath.lastIndexOf(":") + 1);

            routes.push(route);
        } else if (menu.url && /\S/.test(menu.url)) { // \S 非空白
            routes = menuUrl2Route(url,menu,routes);
        }
    }

    if (temp.length >= 1) {
        addDynamicRoutes(temp, routes)
    } else {
        console.log('【配置动态路由】 -- 动态路由加载完成. 最后数据：')
        console.log(routes)
    }

    return routes;
};

function menuUrl2Route(url,menu,routes){
    // 创建路由配置
    let route = {
        path: '/' + url,
        component: null,
        name: menu.index,
        meta: {
            type: 'route',
            icon: menu.icon,
            title: menu.name
        }
    };

    // 根据菜单URL动态加载vue组件，这里要求vue组件须按照url路径存储
    // 如url="sys/user"，则组件路径应是"@/views/sys/user.vue",否则组件加载不到
    let url2Vue = url;
    route['component'] = resolve => require([`@/views/modules/${url2Vue}`], resolve);
    route.meta['componentPoint'] = `@/views/modules/${url2Vue}`;
    routes.push(route);
    return routes;
}


// 跳转后返回顶部
router.afterEach((to,from,next) => {
    window.scrollTo(0,0);
})

export default router;
